<?php
/*-----------------------------------------------------+
 * 公共函数
 * @author yeahoo2000@gmail.com
 +-----------------------------------------------------*/

/**
 * 浏览器友好的变量输出(ThinkPHP)
 * @access public
 * @param  mixed       $var   变量
 * @param  boolean     $echo  是否输出(默认为 true，为 false 则返回输出字符串)
 * @param  string|null $label 标签(默认为空)
 * @param  integer     $flags htmlspecialchars 的标志
 * @return null|string
 */
define('IS_CLI', PHP_SAPI == 'cli' ? true : false);
function dump($var, $echo = true, $label = null, $flags = ENT_SUBSTITUTE)
{
    $label = (null === $label) ? '' : rtrim($label) . ':';

    ob_start();
    var_dump($var);
    $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', ob_get_clean());

    if (IS_CLI) {
        $output = PHP_EOL . $label . $output . PHP_EOL;
    } else {
        if (!extension_loaded('xdebug')) {
            $output = htmlspecialchars($output, $flags);
        }
        //设置字体: "serif"、"sans-serif"、"cursive"、"fantasy"、"monospace"
        $output = '<pre style="font-family:serif;">' . $label . $output . '</pre>';
    }

    if ($echo) {
        echo($output);
        return;
    }

    return $output;
}

/**
 * 打印指定变量的内容(用于调试)
 * @param mixd $var 变量名
 * @param string $label 标签名
 */
function pdump($var, $label = null){
    $content = $label ? "<hr /><strong>$label :</strong>" : '';
    $content .= '<pre>' . htmlspecialchars(print_r($var, true)) . '</pre><hr />';
    echo $content;
}

function p($var){
    $content = '<pre>' . htmlspecialchars(print_r($var, true)) . '</pre>';
    echo $content;
    exit;
}

/**
 * 判断某个字串是否Y-m-d格式的时间字串
 * @param string $date 日期
 * @return bool
 */
function isDate($date){
    $dPat	='([1-9])|((0[1-9])|([1-2][0-9])|(3[0-2]))';
    $mPat	='([1-9])|((0[1-9])|(1[0-2]))';
    $yPat	='(19|20)[0-9]{2}';
    $pattern="!^($yPat)-($mPat)-($dPat)$!";
    return preg_match($pattern, $date);
}

/**
 * 产生一个随机字串
 * @param int $len 指定随机字串的长度
 * @param string $scope 随机字符的取值范围
 * @return string
 */
function randString($len, $scope = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") {
    $strLen = strlen($scope) - 1;
    $string = '';
    for($i = 0; $i < $len; $i ++) {
        $string .= substr($scope, mt_rand( 0, $strLen ), 1);
    }
    return $string;
}

/**
 * 得到客户端IP地址
 * @return string
 */
function clientIp(){
	//return get_ip();
    if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
        $ip = getenv("HTTP_CLIENT_IP");
    else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
        $ip = getenv("HTTP_X_FORWARDED_FOR");
    else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
        $ip = getenv("REMOTE_ADDR");
    else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
        $ip = $_SERVER['REMOTE_ADDR'];
    else
        $ip = "unknown";
    return($ip);
}

/**
 * 获取客户端IP地址(ThinkPHP)
 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
 * @param boolean $adv 是否进行高级模式获取（有可能被伪装） 
 * @return mixed
 */
function get_client_ip($type = 0,$adv=false) {
    $type       =  $type ? 1 : 0;
    static $ip  =   NULL;
    if ($ip !== NULL) return $ip[$type];
    if($adv){
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $pos    =   array_search('unknown',$arr);
            if(false !== $pos) unset($arr[$pos]);
            $ip     =   trim($arr[0]);
        }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip     =   $_SERVER['HTTP_CLIENT_IP'];
        }elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip     =   $_SERVER['REMOTE_ADDR'];
        }
    }elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip     =   $_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证
    $long = sprintf("%u",ip2long($ip));
    $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
    return $ip[$type];
}

/**
 * 发送HTTP状态
 * @param integer $code 状态码
 * @return void
 */
function send_http_status($code) {
    static $_status = array(
            // Informational 1xx
            100 => 'Continue',
            101 => 'Switching Protocols',
            // Success 2xx
            200 => 'OK',
            201 => 'Created',
            202 => 'Accepted',
            203 => 'Non-Authoritative Information',
            204 => 'No Content',
            205 => 'Reset Content',
            206 => 'Partial Content',
            // Redirection 3xx
            300 => 'Multiple Choices',
            301 => 'Moved Permanently',
            302 => 'Moved Temporarily ',  // 1.1
            303 => 'See Other',
            304 => 'Not Modified',
            305 => 'Use Proxy',
            // 306 is deprecated but reserved
            307 => 'Temporary Redirect',
            // Client Error 4xx
            400 => 'Bad Request',
            401 => 'Unauthorized',
            402 => 'Payment Required',
            403 => 'Forbidden',
            404 => 'Not Found',
            405 => 'Method Not Allowed',
            406 => 'Not Acceptable',
            407 => 'Proxy Authentication Required',
            408 => 'Request Timeout',
            409 => 'Conflict',
            410 => 'Gone',
            411 => 'Length Required',
            412 => 'Precondition Failed',
            413 => 'Request Entity Too Large',
            414 => 'Request-URI Too Long',
            415 => 'Unsupported Media Type',
            416 => 'Requested Range Not Satisfiable',
            417 => 'Expectation Failed',
            // Server Error 5xx
            500 => 'Internal Server Error',
            501 => 'Not Implemented',
            502 => 'Bad Gateway',
            503 => 'Service Unavailable',
            504 => 'Gateway Timeout',
            505 => 'HTTP Version Not Supported',
            509 => 'Bandwidth Limit Exceeded'
    );
    if(isset($_status[$code])) {
        header('HTTP/1.1 '.$code.' '.$_status[$code]);
        // 确保FastCGI模式下正常
        header('Status:'.$code.' '.$_status[$code]);
    }
}

/**
 * 字串长度计算(可计算utf8)
 * @param string $str 待计算的字串
 * @return int 长度
 */
function utf8strlen($str) {
    $i = 0;
    $count = 0;
    $len = strlen ( $str );
    while ( $i < $len ) {
        $chr = ord ( $str [$i] );
        $count ++;
        $i ++;
        if ($i >= $len) break;
        if ($chr & 0x80) {
            $chr <<= 1;
            while ( $chr & 0x80 ) {
                $i ++;
                $chr <<= 1;
            }
        }
    }
    return $count;
}

/*
 * 截取中文字符
 * @param string $str 字串
 * @param int $len 截取长度
 * @return string 截取后的字串
 */
function cnSubstr($str, $len) {
    for($i = 0; $i < $len; $i ++) {
        $temp_str = substr ( $str, 0, 1 );
        if (ord ( $temp_str ) > 127) {
            $i ++;
            if ($i < $len) {
                $new_str [] = substr ( $str, 0, 3 );
                $str = substr ( $str, 3 );
            }
        } else {
            $new_str [] = substr ( $str, 0, 1 );
            $str = substr ( $str, 1 );
        }
    }
    return join($new_str);
}

/**
 * 写文件系统
 * @param string $file 文件名
 * @param string $content 内容
 */
function writeFile($file, $content, $mode='wb'){
    $oldMask= umask(0);
    $fp= @fopen($file, $mode);
    fwrite($fp, $content);
    fclose($fp);
    umask($oldMask);
}

/**
 * 将秒转换成可阅读的时间格式
 * @author Tim <mianyangone@gmail.com> 
 * @param int $second 秒数
 * @param string $format 可阅读的构成类型(Y|W|D|H|M)
 * @return string;
 */
function convertTime($second,$format = 'Y'){
    if ($second <= 0 ) return 0;	

    $sM = 60; //60秒
    $sH = $sM * 60; //60 分钟
    $sD = $sH * 24; //24小时
    $sW = $sD * 7; //7天
    $sY = $sD * 365; // 365天

    $string = '';
    $format = strtoupper($format);
    switch ($format){
    case 'Y':
        $y = (int)($second/$sY);
        $second -= $y * $sY;
        if ($y>0) $string .= "$y 年 "; 
    case 'W':
        $w = (int)($second/$sW);
        $second -= $sW * $w;
        if ($w>0) $string .= "$w 周 ";
    case 'D':
        $d = (int)($second/$sD);
        $second -= $sD * $d;
        if ($d>0) $string .= "$d 天 ";
    case 'H':
        $h = (int)($second/$sH);
        $second -= $sH * $h;
        if ($h>0) $string .= "$h 小时 ";
    case 'M':
        $m = (int)($second/$sM);
        $second -= $sM * $m;
        if ($m>0) $string .= "$m 分  ";
        break;
    default:
        convertTime($second,'Y');
    }
    return $string;
}

function secondToString($diff)
{
  if($diff < 60) {
    return intval($diff % 60) . "秒";
  } elseif($diff < 60 * 15) {
    return intval($diff / 60) . "分钟";
  } elseif($diff < 60 * 30) {
    return "一刻钟";
  } elseif($diff < 60 * 60) {
    return "半小时";
  } elseif($diff < 60 * 60 * 24) {
    return intval($diff / 60 / 60) . "小时";
  } elseif($diff < 60 * 60 * 24 * 7) {
    return intval($diff / 60 / 60/ 24) . "天";
  } elseif($diff < 60 * 60 * 24 * 30) {
    return intval($diff / 60 / 60/ 24/7) . "星期";
  } elseif($diff < 60 * 60 * 24 * 365) {
    return intval($diff / 60 / 60/ 24 / 30) . "月";
  } else {
    return intval($diff / 60 / 60/ 24 / 365) . "年";
  }
}

/**
 * 用于开发的时候打印异常信息的
 * @param $e object Exception对象
 * @return unknown_type
 */
function pocketException($e){
    $html = "";
    $html.= "<p>";
    $html.= "<h4>".$e->getMessage()."<h4>";
    $html.= "<h5>".$e->getFile()."【".$e->getLine()."】</h5>";
    $html.= $e->getTraceAsString();
    $html.= "</p>";
    
    echo $html;
}

/**
 * 把数组转成HTML的table
 * @param $ay
 * @return string
 */
function arrayToTable($ay, $flag=0, $style=true){
    if(!is_array($ay)) return "Not array<br>\n";
    if(count($ay)==0)  return "<div style='text-align:center'> - - - </div>";
    
    $t = "";
	if($style){
		$t .= "<style>";
		$t .= ".func_array_to_table{border:1px #333 solid; border-right:none; border-bottom:none; padding:0}";
		$t .= ".func_array_to_table tr{vertical-align: top}";
		$t .= ".func_array_to_table td{border:1px #333 solid; border-left:none; border-top:none; padding:2px}";
		$t .= "</style>";
	}
    $t .= "<p>";
    if($flag){
        $t .="<table class='func_array_to_table' bgcolor=#eefbde cellspacing=0 cellpadding=0>";
        $t .= "<tr>";
        foreach($ay as $k=>$a){
            $t .= "<td><b>$k</b></td>";
        }
        $t .= "</tr>";

        $t .= "<tr>";
        foreach($ay as $a){
            $td = $a;
            if(is_array($a)){
                $td = arrayToTable($a, 1-$flag, false);
            }else if(is_object($a)){
                $td = '<i><font color=blue>'.get_class($a).'</font></i>';
            }else if(!$a && !is_numeric($a)){
                $td = '&nbsp;';
            }

            $t .= "<td>$td</td>";
        }
        $t .= "</tr>\n";
        $t .= '</table>';
    }else{
        $t .= "<table class='func_array_to_table' bgcolor=#ffeedd cellspacing=0 cellpadding=0>";
        foreach($ay as $k=>$a){
            $t .= "<tr>";
            $t .= "<td><b>$k</b></td>";
            $td = $a;
            if(is_array($a)){
                $td = arrayToTable($a, 1-$flag, false);
            }else if(is_object($a)){
                $td = '<i><font color=blue>'.get_class($a).'</font></i>';
                }else if(!$a && !is_numeric($a)){
                $td = '&nbsp;';
            }

            $t .= "<td>$td</td>";
            $t .= "</tr>\n";
        }
        $t .= '</table>';
    }
    $t .= '</p>';
    return $t;
}

// 不区分大小写的in_array实现
function in_array_case($value,$array){
    return in_array(strtolower($value),array_map('strtolower',$array));
}

//xml 格式转数组
function xml_to_array($xml){
    $reg = "/<(\w+)[^>]*>([\\x00-\\xFF]*)<\\/\\1>/";
    if(preg_match_all($reg, $xml, $matches)){
        $count = count($matches[0]);
        for($i = 0; $i < $count; $i++){
        $subxml= $matches[2][$i];
        $key = $matches[1][$i];
            if(preg_match( $reg, $subxml )){
                $arr[$key] = xml_to_array( $subxml );
            }else{
                $arr[$key] = $subxml;
            }
        }
    }
    return $arr;
}
